//Copyright (C) 2013 Julio Espindola
//
//This file is part of VSize Checkers.
//
//VSize Checkers is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//VSize Checkers is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with VSize Checkers.  If not, see <http://www.gnu.org/licenses/>.

package checkers;

import java.util.Collections;

public class Move implements java.io.Serializable
{
    public final int start, dest;
    public final boolean crowning;
    int prevHalfMove;
    
    Move(int start, int dest)
    {
        this.start = start;
        this.dest = dest;
        crowning = false;
    }
    
    Move(int start, int dest, boolean crowning)
    {
        this.start = start;
        this.dest = dest;
        this.crowning = crowning;
    }
    
    void make(Board b)
    {
        prevHalfMove = b.halfMove;
        if(start == dest) {b.halfMove = 0; return;}
       
        byte piece = b.getPiece(start);
        byte newPiece = crowning?(byte)(b.getPiece(start)^Piece.QUEEN):b.getPiece(start);
       
        b.setPiece(dest, newPiece);
        b.hash ^= Board.zobrist[(dest-1)*4 + (newPiece>>2)];
        b.setPiece(start, Piece.EMPTY);
        b.hash ^= Board.zobrist[(start-1)*4 + (piece>>2)];
       
        if(crowning)
        {
            if((b.squares[0]&Board.TURN) == 0) b.whiteMaterial += 2;
            else b.blackMaterial += 2;
        }
        
        if( (piece&Piece.QUEEN)==0 || this instanceof MJumps)
            b.halfMove = 0;
        else
            ++b.halfMove;
    }
   
    void undo(Board b)
    {
        b.halfMove = prevHalfMove;
        if(start == dest) return;
       
        byte piece = b.getPiece(dest);
        byte newPiece = crowning?(byte)(b.getPiece(dest)^Piece.QUEEN):b.getPiece(dest);
       
        b.setPiece(start, newPiece);
        b.hash ^= Board.zobrist[(start-1)*4 + (newPiece>>2)];
        b.setPiece(dest, Piece.EMPTY);
        b.hash ^= Board.zobrist[(dest-1)*4 + (piece>>2)];
       
        if(crowning)
        {
            if((b.squares[0]&Board.TURN) == 0) b.blackMaterial -= 2;
            else b.whiteMaterial -= 2;
        }
    }

    
    public int[] getSquares()
    {
        return new int[]{start, dest};
    }
    
    public int[] getCapSquares()
    {
        return null;
    }
    
    int getSize()
    {
        return 1;
    }
    
    @Override
    public String toString()
    {
        return "===========\nMove: " + start + "-" + dest;
    }
    
    public boolean equals(Object obj)
    {
        Move other = (Move) obj;
        
        return start == other.start
                && dest == other.dest
                && crowning == other.crowning;
    }
}
